package com.cskaoyan.aspect;

import com.cskaoyan.bean.BaseRespVo;
import com.cskaoyan.bean.bo.AdminCreateBO;
import com.cskaoyan.bean.bo.AdminUpdateBO;
import com.cskaoyan.bean.bo.RefundBO;
import com.cskaoyan.bean.bo.ShipBO;
import com.cskaoyan.bean.po.AdminLogPO;
import com.cskaoyan.bean.po.AdminPO;
import com.cskaoyan.service.AdminService;
import com.cskaoyan.service.OrderService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.Map;

@Aspect
@Component
public class LogAspect {
    @Autowired
    OrderService orderService;
    @Autowired
    AdminService adminService;

    @Pointcut("@annotation(com.cskaoyan.annotation.LogAnnotation)")
    public void myPointcut() {
    }

    @Before("myPointcut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        AdminLogPO adminLogPO = judgeTypeByURI(request);
        adminLogPO.setIp(request.getRemoteAddr());
        HttpSession session = request.getSession();
        session.setAttribute("log", adminLogPO);
        // if (request.getRequestURI().contains("ship")) {
        Object[] args = joinPoint.getArgs();
        if (args != null) {
            for (Object arg : args) {
                if (arg instanceof ShipBO) {
                    ShipBO ship = (ShipBO) arg;
                    Integer orderId = ship.getOrderId();
                    String sn = orderService.selectOrderSnByOrderId(orderId);
                    adminLogPO.setResult("订单编号:" + sn);
                }
                if (arg instanceof AdminCreateBO) {
                    AdminCreateBO adminCreateBO = (AdminCreateBO) arg;
                    adminLogPO.setResult(adminCreateBO.getUsername());
                }
                if (arg instanceof AdminUpdateBO) {
                    AdminUpdateBO adminUpdateBO = (AdminUpdateBO) arg;
                    adminLogPO.setResult(adminUpdateBO.getUsername());
                }
                if (arg instanceof RefundBO) {
                    RefundBO refund = (RefundBO) arg;
                    Integer id = refund.getOrderId();
                    String sn = orderService.selectOrderSnByOrderId(id);
                    adminLogPO.setResult("订单编号:" + sn);
                }
            }
        }
//        }else if (request.getRequestURI().contains("refund")) {
//            Object[] args = joinPoint.getArgs();
//            if (args != null) {
//                for (Object arg : args) {
//                    if (arg instanceof RefundBO) {
//                        RefundBO refund = (RefundBO) arg;
//                        Integer id = refund.getOrderId();
//                        String sn = orderService.selectOrderSnByOrderId(id);
//                        adminLogPO.setResult("订单编号:" + sn);
//                    }
//                }
//            }
//        }
    }

    private AdminLogPO judgeTypeByURI(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        AdminLogPO adminLogPO = new AdminLogPO();
        String[] split = requestURI.split("/");
        String s1 = split[2];
        String s2 = split[3];
        if (s1.equals("admin") && s2.equals("update")) {
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(1);
            adminLogPO.setAction("编辑管理员");
            adminLogPO.setDeleted(false);
        } else if (s1.equals("admin") && s2.equals("create")) {
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(1);
            adminLogPO.setAction("新建管理员");
            adminLogPO.setDeleted(false);
        } else if (s1.equals("auth") && s2.equals("login")) {
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(1);
            adminLogPO.setAction("登录");
            adminLogPO.setDeleted(false);
        } else if (s1.equals("auth") && s2.equals("logout")) {
            Subject subject = SecurityUtils.getSubject();
            AdminPO adminPO = (AdminPO) subject.getPrincipals().getPrimaryPrincipal();
            adminLogPO.setAdmin(adminPO.getUsername());
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(1);
            adminLogPO.setAction("退出");
            adminLogPO.setDeleted(false);
            adminLogPO.setStatus(true);
            adminLogPO.setIp(request.getRemoteAddr());
            adminService.insertAdminLog(adminLogPO);
        } else if (s1.equals("admin") && s2.equals("delete")) {
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(1);
            adminLogPO.setAction("删除管理员");
            adminLogPO.setDeleted(false);
        } else if (s1.equals("order") && s2.equals("ship")) {
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(2);
            adminLogPO.setAction("发货");
            adminLogPO.setDeleted(false);
        } else if (s1.equals("order") && s2.equals("refund")) {
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(2);
            adminLogPO.setAction("退款");
            adminLogPO.setDeleted(false);
        } else if (s1.equals("order") && s2.equals("delete")) {
            adminLogPO.setAddTime(new Date());
            adminLogPO.setUpdateTime(new Date());
            adminLogPO.setType(2);
            adminLogPO.setAction("删除订单");
            adminLogPO.setDeleted(false);
        }
        return adminLogPO;
    }

    @AfterReturning(value = "@annotation(com.cskaoyan.annotation.LogAnnotation)", returning = "result")
    public void afterReturning(BaseRespVo result) {

        Subject subject = SecurityUtils.getSubject();
        AdminLogPO log = new AdminLogPO();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        if (!request.getRequestURI().contains("logout")) {
            HttpSession session = request.getSession();
            log = (AdminLogPO) session.getAttribute("log");
            if (subject != null) {
                AdminPO adminPO = (AdminPO) subject.getPrincipals().getPrimaryPrincipal();
                log.setAdmin(adminPO.getUsername());
            }

            AdminLogPO adminLogPO = setAdminPOInfo(log, request.getRequestURI(), result);
            adminService.insertAdminLog(adminLogPO);
        }

    }

    private AdminLogPO setAdminPOInfo(AdminLogPO log, String requestURI, BaseRespVo result) {

        String[] split = requestURI.split("/");
        String s1 = split[2];
        String s2 = split[3];

        if (s1.equals("admin") && s2.equals("update")) {
            log.setStatus(result.getErrno() <= 0);
        } else if (s1.equals("admin") && s2.equals("create")) {
            log.setStatus(result.getErrno() <= 0);
        } else if (s1.equals("auth") && s2.equals("login")) {
            judgeResult(log, result);
        } else if (s1.equals("auth") && s2.equals("logout")) {
            judgeResult(log, result);
        } else if (s1.equals("admin") && s2.equals("delete")) {
            log.setStatus(result.getErrno() <= 0);
        } else if (s1.equals("order") && s2.equals("ship")) {
            log.setStatus(result.getErrno() <= 0);
        } else if (s1.equals("order") && s2.equals("refund")) {
            log.setStatus(result.getErrno() <= 0);
        } else if (s1.equals("order") && s2.equals("delete")) {
            log.setStatus(result.getErrno() <= 0);
        }
        return log;
    }

    private void judgeResult(AdminLogPO log, BaseRespVo result) {
        if (result.getErrno() > 0) {
            log.setStatus(false);
            log.setResult(result.getErrmsg());
        } else {
            log.setStatus(true);
            log.setResult(result.getErrmsg());
        }
    }

}
